package ch.zbw.swt.sysventory.util;

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyChangeListener;

import javax.swing.Action;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import ch.zbw.swt.sysventory.network.IPv4;
import ch.zbw.swt.sysventory.network.ServerIpRead;
import ch.zbw.swt.sysventory.network.scan.ScanMasterClass;
import ch.zbw.swt.sysventory.service.SqlDataReader;
import ch.zbw.swt.sysventory.ui.GUIErrorAnmeldung;
import ch.zbw.swt.sysventory.ui.GUIErrorMenuAuswahl;
import ch.zbw.swt.sysventory.ui.GUIGefundeneObjekte;
import ch.zbw.swt.sysventory.ui.GUILogin;
import ch.zbw.swt.sysventory.ui.GUIMenu;
import ch.zbw.swt.sysventory.ui.GUIScanErfolgV2;
import ch.zbw.swt.sysventory.ui.GUIScannen;
import ch.zbw.swt.sysventory.ui.GUIStatistik;
import ch.zbw.swt.sysventory.ui.GUIStatistikRechner;
import ch.zbw.swt.sysventory.ui.GUIStatistikScanWMJ;
import ch.zbw.swt.sysventory.ui.GUIStatistikSoftware;
import ch.zbw.swt.sysventory.ui.GUIStatistikgewechselteRechner;
import ch.zbw.swt.sysventory.ui.GUISucheV2;

/*
 * Wird als Einstiegsklasse genutzt und verwaltet die GUIs von Sysventory und
 * kommmuniziert mit den Kernklassen für DB und Scan
 */
public class GuiHandler implements Action, KeyListener, WindowListener, ListSelectionListener {

	// Variable für die Verfolgung der momentan aktiven GUI
	private int runWindow;
	
	//Variable für die Verfolgung ob der angemeldte Benutzer Inventor ist
	private boolean isadmin;
	
	//Listener
	private ActionEvent action;
	private KeyEvent key;
	private WindowListener win;
	private ListSelectionListener listener;

	//GUIS
	private GUILogin guilogin;
	private GUIMenu guimenu;
	private GUIScannen guiscannen;
	private GUIScanErfolgV2 guiscanerfolg;

	private GUISucheV2 guisuche;
	private GUIGefundeneObjekte guisuchResult;

	private GUIStatistik guistatistik;
	private GUIStatistikScanWMJ guistatistikScanWMJ;
	private GUIStatistikgewechselteRechner guistatistikgewechselteRechner;
	private GUIStatistikRechner guistatistikRechner;
	private GUIStatistikSoftware guistatistikSoftware;

	//Funktionsvariablen
	
	private IPv4 startIP;
	private IPv4 endIP;
	private IPv4 serverIp;

	//Kommunikationsvariablen zu Kernelemente
	private ScanMasterClass scanMasterClass;
	private ServerIpRead serverIpRead;
	private SqlDataReader datareader;

	/*
	 * KOnstruktor der des GUI-Haendlers
	 */
	public GuiHandler() {
		guilogin = new GUILogin(this, this);
		guilogin.initialize();
		serverIpRead = new ServerIpRead();

	}

	/*
	 * Einstiegspunkt für User - Mainmethode
	 */
	public static void main(String[] args) {
		new GuiHandler();
	}

	/*
	 * Actionlistener für die GUIs: Beim starten einer GUI wird jeweils
	 * der Actionlistener des GUIHandler übergeben. Dieser übernimmt dadurch
	 * das Eventhandling von der GUI. Dadurch musste nicht auf jeder
	 * ein eigenes Eventhandling vorgenommen werden, sondern nur an zentraler
	 * Stelle. Zusätzlich wird das Handling der GUI vereinfacht.
	 */
	public void actionPerformed(ActionEvent e) {

		// reagiert auf den Button Login der GUI Login
		if (e.getActionCommand().equals("go2login")) {
			go2Login();
		}
		
		//reagiert auf Pfeilbutton in der GUI Menu
		if (e.getActionCommand().equals("go2action")) {
			go2action();
		}
		
		//reagiert auf den Pfeilbutton der GUI Scannen (Scan Startmenu)
		if (e.getActionCommand().equals("go2Scan")) {
			go2Scan();
		}

		//reagiert auf den Pfeilbutton in der GUI Scannerfolg
		if (e.getActionCommand().equals("go2detailComputer")) {
			go2DetailComputer();
		}

		//reagiert auf den Pfeilbutton in der GUI SucheV2 (Suche StartMenu)
		if (e.getActionCommand().equals("go2searchResult")) {
			ge2SearchResult();
		}

		//reagiert auf den Pfeilbutton in der GUIStatistik (Statistik StartMenu)
		if (e.getActionCommand().equals("go2statResult")) {
			go2StatResult();
		}

		//regiert in auf den Radionbutton "modizizierte Rechner in Zeitraum" in
		//in der GUIStatistik (Statistik Startgui), und zeigt die Textfelder an.
		if (e.getActionCommand().equals("extendStatOptions")) {
			guistatistik.showTextfield();
		}

		//regiert in auf alle Radiobutton ausser "modizizierte Rechner in Zeitraum" in
		//in der GUIStatistik (Statistik Startgui), und zeigt die Textfelder ausgegraut
		if (e.getActionCommand().equals("hideStatOptions")) {
			guistatistik.hideTextfield();
		}

		//reagiert auf Backpfeil und ruft von jeder GUI aus (ausnahme die Error)
		//das Menu wieder auf.
		if (e.getActionCommand().equals("back2Menu")) {
			back2menu();
		}

	}

	/*
	 * Bei der Passworteingabe gibt es die Möglichkeit den Login über die
	 * Eingabe von Enter durchzuführen.
	 * */
	public void keyPressed(KeyEvent e) {
		if (e.getKeyCode() == (KeyEvent.VK_ENTER)) {
			go2Login();
		}

	}

	/*
	 * Wenn eine Fehlermeldung generiert wird, wird das jeweilige GUI, welches
	 * betroffen ist deaktiviert. Um es wieder zu aktivieren wird beim
	 * Schliessen der Fehlermeldung die ein WindowsEvent generiert, dass
	 * das entsprechende GUI wieder aktiviert. 
	 * 
	 * Fehler können bei dn volgenden GUIS entstehen:
	 * - Login
	 * - Menu
	 * - Scanerfolg
	 * - Statitisk
	 * */
	public void windowClosing(WindowEvent e) {

		switch (runWindow) {
		case 99:
			guilogin.enable();
			break;
		case 0:
			guimenu.enable();
			break;
		case 11:
			guiscanerfolg.enable();
			break;
		case 2:
			guimenu.enable();
			break;
		case 3:
			guistatistik.enable();
			break;
		default:
			break;
		}
	}

	/*
	 * ruft das Hauptmenü wieder auf
	 */
	private void back2menu() {

		guimenu = new GUIMenu(this);
		guimenu.initialize(isadmin);

		switch (runWindow) {
		case 1:
			guiscannen.dispose();
			break;
		case 11:
			guiscanerfolg.dispose();
			break;
		case 2:
			guisuche.dispose();
			break;
		case 21:
			guisuchResult.dispose();
			break;
		case 3:
			guistatistik.dispose();
			break;
		case 31:
			guistatistikScanWMJ.dispose();
			break;
		case 32:
			guistatistikRechner.dispose();
			break;
		case 33:
			guistatistikSoftware.dispose();
			break;
		case 34:
			guistatistikgewechselteRechner.dispose();
			break;
		default:
			break;
		}

	}

	/*
	 * Führt den Loginprozess aus
	 */
	private void go2Login() {
		LoginInformation login = new LoginInformation();

		if (login.compareLogin(guilogin.getUser(), guilogin.getPassword()) == true) {

			if (guilogin.getUser().equalsIgnoreCase("inventor") == true) {
				isadmin = true;
				guilogin.dispose();
				guimenu = new GUIMenu(this);
				guimenu.initialize(isadmin);
			}

			else {
				isadmin = false;
				guilogin.dispose();
				guimenu = new GUIMenu(this);
				guimenu.initialize(isadmin);
			}

		}

		else {
			GUIErrorAnmeldung error = new GUIErrorAnmeldung(this);
			runWindow = 99;
			error.initialize();
			guilogin.setUsernameEmtpy();
			guilogin.setPWEmpty();
			guilogin.setFokus();
			guilogin.disable();

		}
	}

	/*
	 * Ruft aufgrund der Auswahl der Radiobutton die entsprechende GUI auf
	 */
	private void go2action() {

		if (guimenu.getAuswahl() == 1) {
			runWindow = 1;
			serverIp = new IPv4(serverIpRead.getIpAddress(),
					serverIpRead.getSubnetMask());
			guiscannen = new GUIScannen(this);
			guiscannen.initialize(serverIp.getNetIDString(),
					serverIp.getBroadcastAddressString());
			guimenu.dispose();

		}
		if (guimenu.getAuswahl() == 2) {
			runWindow = 2;
			guisuche = new GUISucheV2(this, this);
			guisuche.initialize();
			guimenu.dispose();

		}
		if (guimenu.getAuswahl() == 3) {
			runWindow = 3;
			guistatistik = new GUIStatistik(this);
			guistatistik.initialize();
			guimenu.dispose();
		}

		if (guimenu.getAuswahl() == 0) {
			runWindow = 0;
			GUIErrorMenuAuswahl error = new GUIErrorMenuAuswahl(this);
			error.initialize();
			guimenu.disable();

		}

	}

	/*
	 * Ruft den Scan aus und zeigt die Resultate auf der nachfolgenden GUI an.
	 */
	private void go2Scan() {
		String startIpString = guiscannen.getstartip();
		String endIpString = guiscannen.getendip();
		
		if (startIpString.equals("")  || endIpString.equals("")){
			GUIErrorMenuAuswahl error = new GUIErrorMenuAuswahl(this);
			error.initialize();
			guimenu.disable();
		}
		else if( startIpString.equals(endIpString)){
			
			scanMasterClass = new ScanMasterClass(startIpString);
			scanMasterClass.run();
			guiscanerfolg = new GUIScanErfolgV2(this,
				scanMasterClass.createArray());
			guiscannen.dispose();
			guiscanerfolg.initialize();
			
		}
		
		else {
			IPv4 startIP = new IPv4(startIpString,
					serverIpRead.getSubnetMask());
			IPv4 endIP = new IPv4(endIpString,
					serverIpRead.getSubnetMask());
			if (startIP.checkIfIp1InRangeOfIp2(startIP, serverIp)
					&& endIP.checkIfIp1InRangeOfIp2(endIP, serverIp)) {
				scanMasterClass = new ScanMasterClass(startIP, endIP);
				scanMasterClass.run();
				guiscanerfolg = new GUIScanErfolgV2(this,
					scanMasterClass.createArray());
				guiscannen.dispose();
				guiscanerfolg.initialize();
			}
			else {
			
			guiscannen.setStartIPtxtField(serverIp.getNetIDString());
			guiscannen.setEndIPtxtField(serverIp.getBroadcastAddressString());
			GUIErrorMenuAuswahl error = new GUIErrorMenuAuswahl(this);
			error.initialize();
			guimenu.disable();
		}
		}

	}

	/*
	 * Ruft das Suche GUI auf, wenn man man aus der GUI für den
	 * Scanerfolg kommt.
	 */
	private void go2DetailComputer() {

		String computername = guiscanerfolg.getSelectedcomputername();

		if (computername != null) {
			runWindow = 2;
			guisuche = new GUISucheV2(this, this);
			guisuche.initialize();
			guiscanerfolg.dispose();
		} else {
			GUIErrorMenuAuswahl error = new GUIErrorMenuAuswahl(this);
			error.initialize();
			guiscanerfolg.disable();
		}

	}

	/*
	 * Ruft den Suchvorgang aus und zeigt die Resultate an.
	 */
	private void ge2SearchResult() {

		runWindow = 21;
		guisuchResult = new GUIGefundeneObjekte(this);
		guisuchResult.initialize();
		guisuche.dispose();

	}

	/*
	 * Ruft die gewünschte Statistik an.
	 */
	private void go2StatResult() {

		if (guistatistik.getAuswahl() == 31) {
			runWindow = 31;
			guistatistikScanWMJ = new GUIStatistikScanWMJ(this);
			guistatistikScanWMJ.initialize();
			guistatistik.dispose();
		}

		if (guistatistik.getAuswahl() == 32) {
			runWindow = 32;
			guistatistikRechner = new GUIStatistikRechner(this);
			guistatistikRechner.initialize();
			guistatistik.dispose();
		}
		if (guistatistik.getAuswahl() == 33) {
			runWindow = 33;
			guistatistikSoftware = new GUIStatistikSoftware(this);
			guistatistikSoftware.initialize();
			guistatistik.dispose();
		}
		if (guistatistik.getAuswahl() == 34) {
			runWindow = 34;
			guistatistikgewechselteRechner = new GUIStatistikgewechselteRechner(
					this);
			guistatistikgewechselteRechner.initialize();
			guistatistik.dispose();
		}

		if (guistatistik.getAuswahl() == 0) {
			GUIErrorMenuAuswahl error = new GUIErrorMenuAuswahl(this);
			error.initialize();
			guistatistik.disable();
		}

	}

	/*
	 * regiert auf Auswahl des Rechners in der Suche GUI (Startgui Suche)
	 * */
	public void valueChanged(ListSelectionEvent e) {
		
		if (! e.getValueIsAdjusting())
		{
			String name = guisuche.getComputerName();
		}
		
	}

	
	/*
	 * Pflichtmethoden von div. Listener, welche nicht implementiert wurden 
	 */
	
	public Object getValue(String key) {
		return null;
	}

	public void putValue(String key, Object value) {
		// TODO Auto-generated method stub

	}

	public void setEnabled(boolean b) {
		// TODO Auto-generated method stub

	}

	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return false;
	}

	public void addPropertyChangeListener(PropertyChangeListener listener) {
		// TODO Auto-generated method stub

	}

	public void removePropertyChangeListener(PropertyChangeListener listener) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void windowOpened(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void windowClosed(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void windowIconified(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void windowDeiconified(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void windowActivated(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void windowDeactivated(WindowEvent e) {
		// TODO Auto-generated method stub

	}

	
}
